#include "cute.h"
#include "ide_listener.h"
#include "xml_listener.h"
#include "cute_runner.h"

extern "C" {
#include "lexer.h"
#include "LexVal.h"
#include "lex-tools.h"
#include "parser.h"
#include "Label.h"
}

#include <stdlib.h>
#include <iostream>

using namespace std;

void lexer01() {
	FILE* f=fopen("yaoola_src/lexer01.yaoola","r");

	ASSERT_NOT_EQUAL_TOM("can't open the file",(FILE*)NULL,f);
	int result;

	cout << "yyin=file\n" <<endl;
	yyin=f;
	cout<<"reading symbol..."<<endl;
	result=yylex();
	fclose(f);
	ASSERT_EQUALM("symbol mismatch: expected \"class\"!",262,result);
}

/**tests if the lexer can read an entire correct file.
 *
 * @return
 */
bool test01(){
	FILE* f=fopen("yaoola_src/lexer01.yaoola","r");

	int result=0;
	extern LexVal lexval;

	ASSERT_NOT_EQUAL_TOM("can't open the file",(FILE*)NULL,f);

	printf("yyin=file\n");
	//reloop the file. In this way the text before this one doesn't affect the mark in the input file.
	yylex_destroy();
	yyrestart(f);
	yyset_in(f);
	while ((result=yylex())!=0){ //if the EOF is read, yylex returns 0
		printf("symbol: %s\t\t",yytext);
		//to improve string table format
		if (strlen(yytext)<=7){
			printf("\t");
		}
		printf("token: %3d\t",result);
		switch (result){
		case TOKEN_ID:
		case TOKEN_STRINGCONST: {
			printf("value: %s\n",lexval.sval);
			break;
		}
		case TOKEN_BOOLCONST:{
			printf("value: %s\n",lexval.ival==1?"true":"false");
			break;
		}
		case TOKEN_INTCONST:{
			printf("value: %d\n",lexval.ival);
			break;
		}
		case TOKEN_CHARCONST:{
			printf("value: \"%c\"\n",lexval.ival);
			break;
		}
		case TOKEN_ERROR: {
			printf("value: \"%s\"\n",lexval.sval);
			return false;
		}
		default: {
			printf("\n");
		}
		}
	}
	fclose(f);
}

void runAllTests(int argc, char const *argv[]){
	cute::suite s;
	//TODO add your test here
	s.push_back(CUTE(lexer01));
	s.push_back(CUTE(test01));
	cute::xml_file_opener xmlfile(argc,argv);
	cute::xml_listener<cute::ide_listener<> >  lis(xmlfile.out);
	cute::makeRunner(lis,argc,argv)(s, "AllTests");
}

int main(int argc, char const *argv[]){
    runAllTests(argc,argv);
    return 0;
}



